
package com.sausageking.server;

import java.util.List;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.Days;

import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.common.collect.Lists;
import com.sausageking.server.dao.GenericDao;
import com.sausageking.shared.Merchant;
import com.sausageking.shared.YearPassCodes;
import com.sausageking.shared.YearPassCodes.DayPassCode;
import com.sausageking.shared.YearPassCodes.MonthPassCodes;

public class PassCodeGeneratorImpl implements PassCodeGenerator {

  AuthManager authManager = new AuthManagerImpl();

  @Override
  public YearPassCodes generatePassCodeBook(String merchantId, int year)
      throws EntityNotFoundException {
    GenericDao<Merchant> dao = new GenericDao<Merchant>(Merchant.class);
    Merchant merchant = dao.get(Long.valueOf(merchantId));
    DateTimeZone timeZone = DateTimeZone.forID(merchant.getTimeZoneId());

    return new YearPassCodes().setYear(year).setMerchant(merchantId)
        .setTimeZoneId(merchant.getTimeZoneId() )
        .setMonthPassCodes(getMonthPassCodes(year, timeZone, merchant));
  }

  private List<MonthPassCodes> getMonthPassCodes(int year,
      DateTimeZone timeZone, Merchant merchant) {
    List<MonthPassCodes> monthPassCodes = Lists.newArrayList();
    for (int i = 0; i < 12; i++) {
      monthPassCodes.add(new MonthPassCodes().setMonthOfYear(i));
    }

    DateTime start = new DateTime(year, 1, 1, 0, 0, timeZone);
    int numDaysOfYear = getNumDaysOfYear(year, timeZone);
    for (int i = 0; i < numDaysOfYear; i++) {
      DateTime date = start.plusDays(i);
      DayPassCode dayPassCode = new DayPassCode()
          .setDayOfMonth(date.getDayOfMonth())
          .setDayOfWeek(date.getDayOfWeek())
          .setPassCode(
              authManager.getPurcaseConfirmationCode(merchant, date))
          .setDate(date.toString());
      monthPassCodes.get(date.getMonthOfYear() - 1).addDayPassCode(dayPassCode);
    }
    return monthPassCodes;
  }

  private int getNumDaysOfYear(int year, DateTimeZone timeZone) {
    return Days.daysBetween(
        new DateTime(year, 1, 1, 0, 0, timeZone).toDateMidnight(),
        new DateTime(year + 1, 1, 1, 0, 0, timeZone).toDateMidnight())
        .getDays();
  }
}
